/*****************************************************************************
 * vlc_video_area.c : GTK+ plugin for vlc
 *****************************************************************************/

#include "components/videoarea.h"
#include "intf.h"
#include "vlc_connect.h"


#include <gdk/gdkx.h>

#define VLC_LOGO_WIDTH 128
#define VLC_LOGO_HEIGHT 128

/* Widget */

static void     vlc_video_area_class_init     (VlcVideoAreaClass *klass);
static void     vlc_video_area_realize        (GtkWidget *widget);
static gboolean vlc_video_area_expose         (GtkWidget *widget, GdkEventExpose *event);
static void     vlc_video_area_size_request   (GtkWidget *widget, GtkRequisition *requisition);
static void     vlc_video_area_paint          (GtkWidget *widget);
static void     vlc_video_area_init           (VlcVideoArea *area);

static void     vlc_video_area_destroy    (GtkObject *object);

G_DEFINE_TYPE (VlcVideoArea, vlc_video_area, GTK_TYPE_WIDGET);

/* Video Handling */

static void* DoRequest (intf_thread_t *p_intf, vout_thread_t *p_vout,
                       int *pi1, int *pi2, unsigned int *pi_width, unsigned int *pi_height);
                        
static void  DoRelease (intf_thread_t *p_intf, void *p_win);
static int   DoControl (intf_thread_t *p_intf, void *p_win, int i_q, va_list a);


/* Private */
static gboolean cb_unset_size (gpointer data);
static void cb_set_preferred_size (GtkWidget *widget, GtkRequisition *req, gpointer data);
void vlc_video_area_set_preferred_size (GtkWidget *widget, gint width, gint height);

vlc_mutex_t lock;


static void
vlc_video_area_init (VlcVideoArea *area)
{

  intf_thread_t *p_intf;

  p_intf = VLC_INTF_THREAD;

  p_intf->pf_request_window = DoRequest;
  p_intf->pf_release_window = DoRelease;
  //p_intf->pf_control_window = DoControl;

  area->logo = gdk_pixbuf_new_from_file (DATA_PATH"/vlc128x128.png", NULL);

} 


static void
vlc_video_area_class_init (VlcVideoAreaClass *klass)
{

  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;

  widget_class = GTK_WIDGET_CLASS (klass);

  widget_class->realize = vlc_video_area_realize;
  widget_class->expose_event = vlc_video_area_expose;
  widget_class->size_request = vlc_video_area_size_request;
  
  object_class = GTK_OBJECT_CLASS (klass);
  object_class->destroy = vlc_video_area_destroy;

}

static void
vlc_video_area_size_request (GtkWidget *widget, GtkRequisition *requisition)
{

  requisition->width = 0;
  requisition->height = 0;

}

static void
vlc_video_area_realize (GtkWidget *widget)
{

  GdkWindowAttr attributes;
  gint attributes_mask;
 	GdkColor color;

  g_return_if_fail (GTK_IS_WIDGET (widget));

  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.x = widget->allocation.x;
  attributes.y = widget->allocation.y;
  attributes.width = widget->allocation.width;
  attributes.height = widget->allocation.height;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gtk_widget_get_visual (widget);
  attributes.colormap = gtk_widget_get_colormap (widget);
  attributes.event_mask = gtk_widget_get_events (widget);
  attributes.event_mask |= GDK_EXPOSURE_MASK;

  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;

  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
  gdk_window_set_user_data (widget->window, widget);

  widget->style = gtk_style_attach (widget->style, widget->window);
  
  gdk_color_parse ("#000000", &color); // #000000 = black
	gdk_colormap_alloc_color (attributes.colormap, &color, TRUE, TRUE);
	gdk_window_set_background (widget->window, &color);


  vlc_video_area_set_preferred_size (widget, 240, 180);

}

static gboolean
vlc_video_area_expose (GtkWidget *widget, GdkEventExpose *event)
{

  g_return_val_if_fail (widget != NULL, TRUE);
  g_return_val_if_fail (VLC_IS_VIDEO_AREA (widget), TRUE);
  g_return_val_if_fail (event != NULL, TRUE);

  vlc_video_area_paint (widget);

  return FALSE;

}

static void
vlc_video_area_paint (GtkWidget *widget)
{

  gdk_window_clear_area (widget->window,
                         0,
                         0,
                         widget->allocation.width,
                         widget->allocation.height);
                         
                         
  gdk_pixbuf_render_to_drawable (VLC_VIDEO_AREA (widget)->logo,
                                 GDK_DRAWABLE (widget->window),
                                 NULL,
                                 0,
                                 0,
                                 widget->allocation.width / 2 - VLC_LOGO_WIDTH / 2,
                                 widget->allocation.height / 2 - VLC_LOGO_HEIGHT / 2,
                                 VLC_LOGO_WIDTH,
                                 VLC_LOGO_HEIGHT,
                                 GDK_RGB_DITHER_NORMAL,
                                 1, 
                                 1);
}

GtkWidget*
vlc_video_area_new (void)
{

  return g_object_new (VLC_TYPE_VIDEO_AREA, NULL);

}

static void
vlc_video_area_destroy (GtkObject *object)
{
  
  VlcVideoArea *area;
  VlcVideoAreaClass *klass;
  vout_thread_t *p_vout;
  intf_thread_t *p_intf;
  
  area = VLC_VIDEO_AREA (object);

  if (area->logo != NULL)
   {
    g_object_unref (area->logo);
    area->logo = NULL;
   }

  p_intf = VLC_INTF_THREAD;  
  p_vout = VLC_INTF_SYS->p_vout;

  if (p_vout != NULL)
   {
    if (p_intf->psz_switch_intf == NULL)
     {
      if (vout_Control (p_vout, VOUT_CLOSE) != VLC_SUCCESS)
       {
        vout_Control (p_vout, VOUT_REPARENT);
       }
     }
    else
     {
      if (vout_Control (p_vout, VOUT_REPARENT ) != VLC_SUCCESS)
       {
        vout_Control (p_vout, VOUT_CLOSE);
       }
     }   
   }

  p_intf->pf_request_window = NULL;
  p_intf->pf_release_window = NULL;
  p_intf->pf_control_window = NULL;
 
  klass = gtk_type_class (gtk_widget_get_type ());

  if (GTK_OBJECT_CLASS (klass)->destroy)
   {
     (* GTK_OBJECT_CLASS (klass)->destroy) (object);
   }
}

static void*
DoRequest (intf_thread_t *p_intf, vout_thread_t *p_vout, int *pi1, int *pi2, unsigned int *pi_width, unsigned int *pi_height)
{

  XID xid;
  GtkWidget *widget;

  widget = VLC_INTF_SYS->p_video;
  xid = GDK_WINDOW_XID (widget->window);

  VLC_INTF_SYS->p_vout = p_vout;

  return (void *)xid;
         
}
              
static void
DoRelease (intf_thread_t *p_intf, void *p_win)
{

  p_intf->p_sys->p_vout = NULL;

}

static int DoControl (intf_thread_t *p_intf, void *p_win, int i_q, va_list a)
{
  return 1;
}

static gboolean
cb_unset_size (gpointer data)
{

  GtkWidget *widget;
  
  widget = data;

  gtk_widget_queue_resize_no_redraw (widget);

  return FALSE;

}

static void
cb_set_preferred_size (GtkWidget *widget, GtkRequisition *req, gpointer data)
{

  VlcVPrefSize *size;
  
  size = data;

  req->width = size->width;
  req->height = size->height;

  g_signal_handler_disconnect (widget, size->sig_id);
  g_free (size);
  g_idle_add (cb_unset_size, widget);

}

void
vlc_video_area_set_preferred_size (GtkWidget *widget, gint width, gint height)
{

  VlcVPrefSize *size;
  
  size = g_new (VlcVPrefSize, 1);

  size->width = width;
  size->height = height;
  size->sig_id = g_signal_connect (widget,
                                   "size-request",
				                           G_CALLBACK (cb_set_preferred_size),
				                           size);

  gtk_widget_queue_resize (widget);

}

